# -*- coding: utf-8 -*-

from mutagen.mp3 import MP3
from mutagen.id3 import ID3, TRCK, TIT2, TPE1, TALB
import gdata.youtube
import gdata.youtube.service
import subprocess
import os,time,shutil,mutagen

yt_service = gdata.youtube.service.YouTubeService()
yt_service.ssl = True


'''
Util functions
'''
#get pure youtube link without extra infos
def pureLink(l):
	chunks = l.split('&')
	return chunks[0]


'''
Class that handle youtube downloading process.
'''
class GetSongProcess():
	def __init__(self,parent):
		self.parent = parent
		
		self.yt_service = gdata.youtube.service.YouTubeService()
		self.yt_service.ssl = True
		
		self.hasProp = False
		self.hasTags = False
		
		#status code:
		# 0 - mp3 ready
		# 1 - encoding
		# 2 - downloading
		# 3 - preparing
		self.status = 3
	
	def enableTags(self):
		self.hasTags = True
	
	def setAuthor(self,a):
		self.tAuthor = a
	
	def setAlbum(self,a):
		self.tAlbum = a
	
	def setTrack(self,t):
		self.tTrack = t
	
	def setTitle(self,t):
		self.tTitle = t

	#used to retrieve some simple metadata
	def GetFirstEntryDetails(self,search_terms):
		
		#get the unique string id of video e.g.
		# http://www.youtube.com?v=XKXKXKX&feature_player=fromec is XKXKXKX
		chunks = search_terms.split("v=")
		s = chunks[-1]
		chunks = s.split("&")
		s = chunks[0]
		
		#preparing youtube query
		yt_service = gdata.youtube.service.YouTubeService()
		query = gdata.youtube.service.YouTubeVideoQuery()
		query.vq = search_terms
		query.racy = 'include'
		query.max_results = 1
		feed = yt_service.YouTubeQuery(query)
		
		#if results are not empty store data into objects
		if not len(feed.entry) == 0:
			self.title = feed.entry[0].media.title.text #TITLE
			self.safetitle = filter(lambda c: c not in '"/\\\'', self.title)#TITLE to be used when passed to dl script
			self.cat = feed.entry[0].media.category[0].text #CATEGORY got directly from youtube
			self.link = pureLink(feed.entry[0].media.player.url) #LINK to the yt video
			self.hasProp = True #used to know if some properties has been cached before
			return [self.title, self.cat] #return a list containing TITLE and CATEGORY
	
	#get pure link of first result url
	def GetFirstResultUrl(self,feed):
		if not len(feed.entry) == 0:
			safetitle = filter(lambda c: c not in '"/\\\'', feed.entry[0].media.title.text)#TITLE to be used when passed to dl script
			return [pureLink(feed.entry[0].media.player.url), safetitle]
	
	#if not cached, search youtube for video
	# obsolete method now...
	# to be deleted.
	def Search(self,search_terms):
		if self.hasProp == False:
			yt_service = gdata.youtube.service.YouTubeService()
			query = gdata.youtube.service.YouTubeVideoQuery()
			query.vq = search_terms
			#query.orderby = 'viewCount'	#I'd rather prefer youtube smart search engine :)
			query.racy = 'include'
			query.max_results = 1
			feed = yt_service.YouTubeQuery(query)
			return self.GetFirstResultUrl(feed)
		else:
			#cache search result
			return [self.link,self.safetitle] 
	
	#get youtube video
	def GetYTVideo(self,data):
		self.status = 2 #downloading status
		# execute the code
		test = 'perl gfv/get_flash_videos -r medium -f "'+ data[1] +'.mp4" '+ data[0]
		self.getVideo = subprocess.Popen(test, shell=True, stdout=None)
		# give it time to respond
		self.getVideo.poll()
		self.filename = data[1]
		return data[1]

	def Video2Mp3(self,file):
		self.origSongName = file+'.'+self.parent.AudioFormat
		self.origVideoName = file+'.mp4'
		self.status = 1 #enconding status
		# execute the code
		if self.parent.AudioFormat == "mp3":
			test = 'ffmpeg -i "'+file+'.mp4" -ac 2 -f wav - | lame --preset standard - "'+file+'.mp3"'
		elif self.parent.AudioFormat == "ogg":
			test = 'ffmpeg -i "'+file+'.mp4" -ac 2 -f wav - | oggenc -o "'+file+'.ogg" /dev/stdin'
		self.encodeSong = subprocess.Popen(test, shell=True, stdout=None)
		# give it time to respond
		self.encodeSong.poll()
		self.fileToBeRemoved = file
	
	#update object status like stopping one process and setting up the next
	# e.g. youtube -> download -> encode -> remove video
	def update(self):
		if self.status == 3:
			if self.parent.areThereSlots() == True:
				self.parent.getSlot()
				self.GetYTVideo(self.tempData)
		if self.status == 2:
			if self.getVideo.poll() != None:
				self.Video2Mp3(self.filename)
	
	def GetStatus(self):
		if self.status == 1:
			if self.encodeSong.poll() != None:
				# if setted remove ripped video and return
				if self.parent.MantainAudioVideo == "no":
					os.remove(self.fileToBeRemoved+".mp4")
				else:
					shutil.move(self.origVideoName,self.parent.VideoFolder)
				
				#if tags are enabled, edit file before moving
				if self.hasTags == True:
					if self.parent.AudioFormat == "mp3":
						#apply ID3TAG before moving file
						song = MP3(self.origSongName)
						song["TRCK"] = TRCK(encoding=3, text=self.tTrack)
						song["TIT2"] = TIT2(encoding=3, text=self.tTitle)
						song["TPE1"] = TPE1(encoding=3, text=self.tAuthor)
						song["TALB"] = TALB(encoding=3, text=self.tAlbum)
						song.save()
					elif self.parent.AudioFormat == "ogg":
						song = mutagen.File(self.origSongName)
						song["title"] = self.tTitle
						song["artist"] = self.tAuthor
						song["album"] = self.tAlbum
						song["track"] = self.tTrack
						song.save()
				
				shutil.move(self.origSongName,self.parent.AudioFolder)
				self.parent.releaseSlot() #releasing download slot
				return 0
		return self.status
		
	def GetSongFromLink(self,link):
		if self.parent.areThereSlots() == True:
			self.parent.getSlot()
			self.GetYTVideo([pureLink(link.__str__()),self.safetitle])
		else:
			self.tempData = [pureLink(link.__str__()),self.safetitle]
			
		
	def GetSong(self, q):
		if self.parent.areThereSlots() == True:
			self.parent.getSlot()
			self.GetYTVideo(self.Search(str(q)))
		else:
			self.tempData = self.Search(str(q))


'''
Class that handle megavideo downloading process.
Very similar to youtube one.
'''
class GetMovieProcess:
	def __init__(self,link,title,parent):
		self.parent = parent
		self.link = link
		self.title = title
		
		#status code:
		# 0 - mp3 ready
		# 1 - encoding  <--- not used in this class but kept it to avoid compatibility issues
		# 2 - downloading
		# 3 - preparing
		self.status = 3
	
	#get youtube video
	def getMegaVideo(self):
		self.status = 2 #downloading status
		# execute the code
		test = 'perl gfv/get_flash_videos -r medium -f "'+ self.title +'.flv" '+ self.link
		self.getVideo = subprocess.Popen(test, shell=True, stdout=None)
		# give it time to respond
		self.getVideo.poll()
	
	
	#here for compatibility
	def update(self):
		pass
	
	def GetStatus(self):
		if self.status == 2:
			if self.getVideo.poll() != None:
				shutil.move(self.title+".flv",self.parent.VideoFolder)
				return 0
		return self.status
		
		
	def getMovie(self, q):
		self.getMegaVideo(str(q))
